#!/usr/bin/env python
#
# Copyright 2007 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from google.appengine.api import users, mail
import simplejson
from google.appengine.ext import webapp, db
from google.appengine.ext.webapp import util
from models import Package, Qtifile
import time
import zipfile
from StringIO import StringIO

DEFAULTQTICONTENTS="""<assessmentItem adaptive="false" identifier="**IDENTIFIER**" timeDependent="false" title="**TITLE**" toolName="CompassExport" toolVersion="1.0" xmlns="http://www.imsglobal.org/xsd/imsqti_v2p0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqti_v2p0 imsqti_v2p0.xsd">
  <itemBody class="likert">
  </itemBody>
</assessmentItem>
"""





def buildpackage(thepackage):

  # loosly based on http://www.tareandshare.com/2008/09/28/Zip-Google-App-Engine-GAE/ 
  # which is full of errors
  # create the zip stream
  zipstream=StringIO()
  file = zipfile.ZipFile(zipstream,"w")
  #make the manifest
  strXML="""<?xml version="1.0" encoding="UTF-8"?>
<manifest identifier="x-ims-plirid-v0::5902c0f44c774cafa216e202cc6bf05e" version="IMS CP 1.1.4" xmlns="http://www.imsglobal.org/xsd/imscp_v1p1" xmlns:imsmd="http://www.imsglobal.org/xsd/imsmd_v1p2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/imscp_v1p1 imscp_v1p1.xsd http://www.imsglobal.org/xsd/imsmd_v1p2 imsmd_v1p2p4.xsd">
<organizations default="first">
<organization identifier="first" structure="hierarchical">
<title>""" + thepackage.name + """</title>"""

  itemXML=""
  resourceXML=""
  # for every tool in the package
  ts=Qtifile.all()
  ts.filter('package =',thepackage)
  ts.order('name')
  for t in ts.fetch(500):
    #add it to the zip file
    file.writestr(str(t.key().id()) + ".xml",  '<?xml version="1.0" encoding="UTF-8"?>' + t.contents.encode('ascii','ignore'))
    # add a manifest item
    itemXML=itemXML + '<item identifier="ITEM-' + str(t.key().id()) + '" identifierref="' + str(t.key().id()) + '" isvisible="true">'
    itemXML=itemXML + '<title>' + t.name + '</title></item>'
    # add a manifest resource
    resourceXML=resourceXML + '<resource href="' + str(t.key().id()) + '.xml" identifier="' + str(t.key().id()) + '" type="imsqti_item_xmlv2p0">'
    resourceXML=resourceXML + '<file href="' + str(t.key().id()) + '.xml" /></resource>'

  # write the manifest
  strXML=strXML + itemXML + '</organization></organizations><resources>' + resourceXML + '</resources></manifest>'
  file.writestr("imsmanifest.xml", strXML.encode('ascii','ignore'))
          
  # we have finished with the zip so package it up and write the directory
  file.close()
  return zipstream



class RootHandler(webapp.RequestHandler):
    def get(self):
      user = users.get_current_user()
      if user:
        self.redirect('/static/content.htm')
      else: # redirect to a login page
        self.redirect(users.create_login_url(self.request.uri))
          
          
class MainHandler(webapp.RequestHandler):
    def get(self, category):
      # have they logged in 
      user = users.get_current_user()
      if category=='blah':
        pass
      if user:
        if category[0:5]=='tool/':
          self.response.headers['Content-Type'] = 'text/xml'
          t=Qtifile.get_by_id(int(category[5:]))
          self.response.out.write(t.contents)
          
        if category[0:5]=='down/':
          # say it's a zip file and give it a file name
          self.response.headers['Content-Type'] = 'application/qip'
          p=Package.get_by_id(int(category[5:]))
          self.response.headers['Content-Disposition'] = 'attachment; filename="' + p.name + '.qip"'
          
          zipstream=buildpackage(p)
          
          #send it out
          zipstream.seek(0)
          while True:
            buf=zipstream.read(2048)
            if buf=="": break
            self.response.out.write(buf)

        if category[0:5]=='mail/':
          
          #build the package 
          p=Package.get_by_id(int(category[5:]))
          
          mail.send_mail(sender= user.email(),
            to=user.nickname() + ' <' +  user.email() + '>',
            subject=p.name,
            body="""can be downloaded from """ + self.request.url.replace('/mail/','/down/')
            )
          self.response.out.write(simplejson.dumps({'address': user.email()}))

      else: # redirect to a login page
          self.redirect(users.create_login_url(self.request.uri))

    def post(self,category):
      user = users.get_current_user()
      result="noop"

      if user:
        newcat=category
        vars=simplejson.loads(self.request.get('posted'))
        
        if newcat=='delete_tool':
          t=Qtifile.get_by_id(int(vars["id"]))
          vars["id"]=str(t.package.key().id())
          t.delete()
          newcat='show_package'
          
        if newcat=='delete_package':
          p=Package.get_by_id(int(vars["id"]))
          ts=Qtifile.all()
          ts.filter('package =',p)
          listTools=[]
          for t in ts.fetch(500):
            t.delete()
          p.delete()
          newcat='list_packages'
          
        if newcat=='save_tool':
          t=Qtifile.get_by_id(int(vars['id']))
          t.name=vars['name']
          t.contents=vars['contents']
          t.put()
          
        if newcat=='create_tool':
          p=Package.get_by_id(int(vars["id"]))
          
          t=Qtifile(package=p, creator=user, name=vars["name"])
          t.put()
          #result=t.key().id()
          t.contents=DEFAULTQTICONTENTS.replace("**TITLE**", vars["name"]).replace("**IDENTIFIER**", "tool-" + str(t.key().id()))
          t.put()
          newcat='show_package'
          
        if newcat=='create_package':
          # Create a folder and manifest to become a QTI package
          p=Package(creator=user, name=vars["name"], desc=vars["desc"])
          p.put()
          #result=p.key().id()
          newcat='list_packages'
          
        if category=='show_tool':
          t=Qtifile.get_by_id(int(vars["id"]))
          result={'key':t.key().id(),'name':t.name, 'contents':t.contents}

        if newcat=='show_package':
          p=Package.get_by_id(int(vars["id"]))
          ts=Qtifile.all()
          ts.filter('package =',p)
          ts.order('name')
          listTools=[]
          for t in ts.fetch(500):
            listTools.append({'key':t.key().id(),'name':t.name})
          result={'key':p.key().id(),'name':p.name, 'desc':p.desc, 'tools': listTools}
          
        if newcat=='list_packages':
          ps=Package.all()
          ps.filter('creator =',user)
          ps.order('name')
          listResult=[]
          for p in ps.fetch(500):
            listResult.append({'key':p.key().id(),'name':p.name, 'desc':p.desc  })
          result=listResult
        
        self.response.headers['Content-Type'] = 'text/javascript'
        self.response.out.write(simplejson.dumps(result))
        
        
      else: # redirect to a login page
          self.redirect(users.create_login_url(self.request.uri))

def main():
    application = webapp.WSGIApplication([('/(.*)/', MainHandler), ('/', RootHandler)],
                                         debug=True)
    util.run_wsgi_app(application)


if __name__ == '__main__':
    main()
